package cn.sh.cares.tools.srcgen.freemarker;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.sh.cares.tools.srcgen.Generator;
import cn.sh.cares.tools.srcgen.SourceGenerator;
import cn.sh.cares.tools.srcgen.db.TableDefinition;
import cn.sh.cares.tools.srcgen.util.ResourceManager;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

public abstract class FreeMarkerGenerator implements Generator {
	
	private static final Log log = LogFactory.getLog(SourceGenerator.class);  
	
	public abstract String generateFileName(TableDefinition tableDefinition);
	
	public abstract String getOutputDirectory();
	
	public abstract String getTemplateFileName();
	
	public String getTemplateDirectory() {
		return ResourceManager.getMessage("template.dir");
	}
	
	public boolean isMerge() {
		return true;
	}
	
	public Map<String, Object> create(TableDefinition tableDefinition) {
		Map<String, Object> templateData = new HashMap<String, Object>();
		
		templateData.put("model", tableDefinition);
		
		return templateData;
	}
	
	public void generate(List<TableDefinition> tableDefinitions) {
		OutputStreamWriter out = null;
		Configuration cfg = new Configuration();
		try {
			File outputDir = new File(getOutputDirectory());
			if (outputDir.exists() && !isMerge()) {
				outputDir.delete();
				outputDir.mkdirs();
			} else if (!outputDir.exists()) {
				outputDir.mkdirs();				
			}
			
			cfg.setDirectoryForTemplateLoading(new File(getTemplateDirectory()));
			cfg.setObjectWrapper(new DefaultObjectWrapper());
			Template t = cfg.getTemplate(getTemplateFileName());
			
			for (TableDefinition tableDefinition : tableDefinitions) {
				
				log.debug("generate " + generateFileName(tableDefinition));
				
				File javaFile = new File(getOutputDirectory() + generateFileName(tableDefinition));
				if (javaFile.exists()) {
					javaFile.delete();
				}
				javaFile.createNewFile();
				out = new OutputStreamWriter(new FileOutputStream(javaFile), "UTF-8");
				t.process(create(tableDefinition), out);
				
				// TODO merge
			}
			
		} catch (Exception e) {
			// ignore
			e.printStackTrace();
		} finally {
			if (out != null) { try { out.close(); } catch (IOException e) {} }
		}
	}

}
